﻿/*
  Copyright (c) 2011, Mikheev Rostislav
  Copyright (c) 2011, FreshFarsh team

  Steel Engine source code is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
/**
  @author Mikheev Rostislav <hacenator@gmail.com>
  @date 23.03.2011
  @brief File IO source file
*/

#include "io_file.h"

namespace _STEEL_NAMESPACE {

IOFile::IOFile() :
  _file_handler(0),
  _file_size(0),
  _file_name(NULL)
{

}

IOFile::IOFile(const char * filename, const char * mode) {
        Open(filename, mode);
}

IOFile::~IOFile() {
  Close();

        delete [] _file_name;
}

bool IOFile::Open(const char * filename, const char * mode) {
        // filname copy
        int len = strlen(filename);
        _file_name = new char[len + 1];
        strcpy(_file_name, filename);

  // open file
        _file_handler = fopen(filename, mode);

        //LOG_INFO("IOFile::open::Loading file '%s' with mode '%s'", filename, mode);
        if (_file_handler == NULL) {
                //sLog->Errorf("IOFile::open::Can't open file '%s' to '%s'", filename, mode);
                return false;
        }

  // get file size
        fseek(_file_handler, 0, SEEK_END);
        _file_size = ftell(_file_handler);
        rewind(_file_handler);

        return true;
}

void IOFile::Close() {
        if (Opened())
                fclose(_file_handler);
}

int IOFile::Size() {
        return _file_size;
}

int IOFile::Seek(long offset, int whence) {
  return fseek(_file_handler, offset, whence);
}

long IOFile::Tell() {
  return ftell(_file_handler);
}

int IOFile::Read(const void* buffer, const int size) {
  if (size == 0)
    return fread(const_cast<void*>(buffer), 1, _file_size, _file_handler);
  else
    return fread(const_cast<void*>(buffer), 1, size, _file_handler);
}

bool IOFile::Write(const void* buffer, const int size) {
  return (fwrite(const_cast<void*>(buffer), size, 1, _file_handler) != 0);
}

void IOFile::WriteString(const char * buffer) {
  fputs(buffer, _file_handler);
}

///--------------------------------------------------------------------------
// Utils function
///--------------------------------------------------------------------------
//TODO(hacenator): make inline and take out to single file?!
bool FileExists(const char * filename) {
/*#ifdef _WIN32
  _finddata_t data;

  long find = _findfirst(filename, &data);

  if (find != -1) {
    _findclose(find);
    return true;
  }

  return false;
#elif __linux__
#endif*/
  struct stat file_info;
  int file_stat;

  file_stat = stat(filename, &file_info);
  if (file_stat == 0)
    return true;

  return false;
  
//TODO(hacenator): Linux implementation
}

}
